package com.gitee.baqkft.code.ui.dlg;

import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.gitee.baqkft.code.ui.component.JavaModelConfigPanel;
import com.gitee.baqkft.code.ui.component.TableConfigPanel;
import com.gitee.baqkft.code.ui.layout.GBC;
import org.apache.ibatis.annotations.Mapper;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 * MyBatis plus代码生成配置
 * @Author: chenmingcai
 * @Date 2020/6/17 8:41 下午
 **/

public class MybatisPlusGeneratorFrame extends JFrame
{
    /**
     * 配置面板
     */
    private final JavaModelConfigPanel configPanel;

    /**
     * 模块配置
     */
    private final TableConfigPanel tableConfigPanel;

    /**
     * 消息列表
     */
    private final DefaultListModel<String> listModel;

    /**
     * 数据源配置
     */
    private final DataSourceConfig dataSourceConfig;

    public MybatisPlusGeneratorFrame(DataSourceConfig dataSourceConfig, String tableName)
    {
        this.dataSourceConfig = dataSourceConfig;
        listModel = new DefaultListModel<>();

        setSize(600, 400);

        setLayout(new GridBagLayout());
        configPanel = new JavaModelConfigPanel();
        GBC gbc = new GBC(0, 0, 1, 1);
        gbc.setWeight(1, 0).setFill(GBC.HORIZONTAL);
        add(configPanel, gbc);
        configPanel.setBorder(BorderFactory.createTitledBorder("全局配置"));

        tableConfigPanel = new TableConfigPanel(tableName);
        gbc = new GBC(0, 1, 1, 1);
        gbc.setWeight(1, 0).setFill(GBC.HORIZONTAL);
        add(tableConfigPanel, gbc);
        tableConfigPanel.setBorder(BorderFactory.createTitledBorder("模块配置"));

        JPanel buttonPanel = createOperatePanel();
        gbc = new GBC(0, 2, 1, 1);
        gbc.setWeight(1, 0).setFill(GBC.HORIZONTAL);
        add(buttonPanel, gbc);

        JList messages = new JList(listModel);
        gbc = new GBC(0, 3, 1, 1);
        gbc.setWeight(1, 1).setFill(GBC.BOTH);
        add(new JScrollPane(messages), gbc);
    }

    /**
     * 创建按钮操作
     * @return
     */
    private JPanel createOperatePanel()
    {
        JPanel panel = new JPanel();
        panel.setLayout(new GridBagLayout());

        JPanel space1 = new JPanel();
        GBC gbc = new GBC(0, 0, 1, 1);
        gbc.setWeight(1, 0).setFill(GBC.HORIZONTAL);
        panel.add(space1, gbc);

        JButton btnGenerate = new JButton("生成");
        gbc = new GBC(1, 0, 1,1);
        gbc.setWeight(0, 0);
        panel.add(btnGenerate, gbc);

        JPanel space2 = new JPanel();
        gbc = new GBC(2, 0, 1, 1);
        gbc.setWeight(1, 0).setFill(GBC.HORIZONTAL);
        panel.add(space2, gbc);

        btnGenerate.addActionListener(this::generate);

        return panel;
    }

    /**
     * 生成代码
     */
    public void generate(ActionEvent event)
    {
        appendMessage("正在应用配置...");
        final AutoGenerator generator = new AutoGenerator(dataSourceConfig);

        //配置
        final GlobalConfig config = new GlobalConfig.Builder()
                .outputDir(configPanel.getTargetProject())
                .author("Chen Mingcai")
                .commentDate("yyyy-MM-dd HH:mm:ss")
                .disableOpenDir()
                .build();

        final String objectName = tableConfigPanel.getObjectName();

        //包配置
        PackageConfig packageConfig = new PackageConfig.Builder()
                .parent(configPanel.getTargetPackage())
                .entity("entity")
                .mapper("mapper")
                .service("service")
                .serviceImpl("service.impl")
                .xml("mapper")
                .build();

        //配置模板
        TemplateConfig templateConfig = new TemplateConfig.Builder()
                .xml(null)
                .build();

        //策略配置
        final StrategyConfig strategyConfig = new StrategyConfig.Builder()
                .addInclude(tableConfigPanel.getTableName())
                .mapperBuilder().mapperAnnotation(Mapper.class).convertMapperFileName(entity->String.format("%sMapper", entity))
                .formatXmlFileName("%s.xml")
                .entityBuilder().columnNaming(NamingStrategy.underline_to_camel).naming(NamingStrategy.underline_to_camel)
                .controllerBuilder().convertFileName(entityName -> entityName + "Controller").enableRestStyle()
                .serviceBuilder().convertServiceFileName(entityName -> String.format("I%sService", entityName))
                .convertServiceImplFileName(entityName -> entityName + "ServiceImpl")
                .build();
        final ConfigBuilder configBuilder = new ConfigBuilder(packageConfig, dataSourceConfig, strategyConfig,
                templateConfig, config, null);
        generator.config(configBuilder);


        //数据源配置
        appendMessage("开始生成...");
        try
        {
            generator.execute(new FreemarkerTemplateEngine());
            appendMessage("生成成功");
        }
        catch (Exception ex)
        {
            appendMessage("生成失败:" + ex.getMessage());
        }
    }

    /**
     * 显示消息
     * @param message
     */
    private void appendMessage(String message)
    {
        StringBuffer buffer = new StringBuffer();
        LocalDateTime now = LocalDateTime.now();
        buffer.append(now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        buffer.append(": ").append(message);
        EventQueue.invokeLater(()->{
            listModel.add(0, buffer.toString());
        });
    }
}
